package com.iwdnb.gkgz.common.quota;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import com.iwdnb.gkgz.common.model.dto.StockDayData;
import com.iwdnb.gkgz.common.utils.BigDecimalUtils;
import com.iwdnb.gkgz.common.utils.StockUtils;

/**
 * 首先计算N日内最高价和最低价的波动范围（HN和LN）：
 *
 * HN = MAX(HIGH, N)
 *
 * LN = MIN(LOW, N)
 *
 * 然后计算当日的WR指标：
 *
 * WR = 100 * (HN - CLOSE) / (HN - LN)
 */
public class WRIndicator {
    public static final String QUOTA_NAME = "wr";
    private static final Integer PERIOD = 10;

    public static void calculateWR(List<StockDayData> stockDayDataList) {
        calculateWR(stockDayDataList, PERIOD);
    }

    public static void calculateWR(List<StockDayData> stockDayDataList, int period) {
        List<Double> list = doCalculateWR(stockDayDataList, period);
        int size = stockDayDataList.size();
        for (int i = 0; i < size; i++) {
            StockDayData stockDayData = stockDayDataList.get(i);
            Double d = list.get(i);
            BigDecimal data = BigDecimalUtils.of(d);
            StockUtils.setStockQuota(stockDayData, QUOTA_NAME, data);
            StockUtils.setStockQuota(stockDayData, QUOTA_NAME + period, data);

        }
    }

    private static List<Double> doCalculateWR(List<StockDayData> stockDayDataList, int period) {
        List<Double> wrList = new ArrayList<>();
        if (stockDayDataList.size() < period) {return new ArrayList<>();}
        Double high = 0d;
        Double low = stockDayDataList.get(0).getClosePrice().doubleValue();
        for (int i = 0; i < stockDayDataList.size(); i++) {
            StockDayData data = stockDayDataList.get(i);
            double closePrice = data.getClosePrice().doubleValue();
            if (closePrice > high) {
                high = closePrice;
            }
            if (closePrice < low) {
                low = closePrice;
            }
            double wr = 0d;
            if (i >= period) {
                wr = 100 * (high - closePrice) / (high - low);
            }
            wrList.add(wr);
        }
        return wrList;
    }

}